package com.luo.chengrui.datapermission.rules;

import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.schema.Column;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 默认权限规则处理器
 */
public class DefaultDataPermissionRule<E extends Expression> implements DataPermissionRule {


    static final Expression EXPRESSION_NULL = new NullValue();


    protected final Map<String, String> tableAndColumns = new HashMap<>();
    /**
     * 所有表名，需要进行权限过滤的表名
     */
    protected final Set<String> TABLE_NAMES = new HashSet<>();

    /**
     * 获取权限范围的接口
     */
    private CustomerPermissionFunction permissionFunction;

    public DefaultDataPermissionRule(CustomerPermissionFunction permissionFunction) {
        this.permissionFunction = permissionFunction;
    }

    /**
     * 添加需要过滤的表和字段
     *
     * @param tableName  表名
     * @param columnName 字段名
     */
    public void addTableAndColumn(String tableName, String columnName) {
        tableAndColumns.put(tableName, columnName);
        TABLE_NAMES.add(tableName);
    }

    public interface CustomerPermissionFunction<E extends Expression> {
        Set<E> getPermission();
    }


    /**
     * 获取所有需要按部门权限过滤的表
     *
     * @return
     */
    @Override
    public Set<String> getTableNames() {
        return TABLE_NAMES;
    }

    @Override
    public Expression getExpression(String tableName, Alias tableAlias) {

        // 获取用户的权限
        Set<E> deptIds = permissionFunction.getPermission();
        if (deptIds == null) {
            //表示 不进行权限过滤，即有所有权限。
            return null;
        }
        //进行数据权限过滤
        if (Objects.nonNull(tableAndColumns.get(tableName)) && deptIds != null && deptIds.size() > 0) {
            return new InExpression(buildColumn(tableName, tableAlias, tableAndColumns.get(tableName)),
                    new ExpressionList(deptIds.stream().collect(Collectors.toList())));
        }

        //没有任何数据权限，查询结果将为是空；
        return EXPRESSION_NULL;
        //


    }

    /**
     * 构建 Column 对象
     *
     * @param tableName  表名
     * @param tableAlias 别名
     * @param column     字段名
     * @return Column 对象
     */
    public static Column buildColumn(String tableName, Alias tableAlias, String column) {
        if (tableAlias != null) {
            tableName = tableAlias.getName();
        }
        return new Column(tableName + "." + column);
    }
}
